package edu.szte.ovrt.datahandler.core;

import java.util.HashMap;
import java.util.Map;

import org.junit.*;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;

import static org.junit.Assert.*;

import edu.szte.ovrt.datahandler.test.MockIOFactory;

@RunWith(PowerMockRunner.class)
public class IOMetaFactory_getIOFactoryTest {
	private Map<String, Class<? extends IOFactory>> m_map;
	private Map<String, Class<? extends IOFactory>> m_orignalMap;

	@Before
	public void emptyMap() {
		m_map = Whitebox.getInternalState(IOMetaFactory.class, "s_factoryMap");
		m_orignalMap = new HashMap<String, Class<? extends IOFactory>>(m_map);
		m_map.clear();
	}

	@After
	public void resetMap() {
		m_map.clear();
		m_map.putAll(m_orignalMap);
	}

	@Test
	public void testGetIOFactoryGood() {
		m_map.put("extension", MockIOFactory.class);

		final IOFactory goodFactory = IOMetaFactory.getInstance().getIOFactory("good.extension");

		assertNotNull(goodFactory);
		assertEquals(MockIOFactory.class, goodFactory.getClass());
	}

	@Test
	public void testGetIOFactoryNoSuchEntry() {
		// don't put anything inside the map
		final IOFactory badFactory = IOMetaFactory.getInstance().getIOFactory("");
		assertNull(badFactory);
	}

	@Test
	public void testGetIOFactoryNullClass() {
		m_map.put("null", null);
		assertNull(IOMetaFactory.getInstance().getIOFactory(".null"));
	}

	// // These two methods of mocking new could work but not, need a check by a PowerMock expert
	// @Test
	// public void testGetIOFactoryInstantiationException() throws Exception {
	// expectNew(MockIOFactory.class).andThrow(new InstantiationException("test"));
	// m_map.put("", MockIOFactory.class);
	// replay(MockIOFactory.class);
	//
	// final IOFactory factory = IOMetaFactory.getInstance().getIOFactory("");
	//
	// assertNotNull(factory);
	// verify(MockIOFactory.class);
	// }
	// @Test
	// @SuppressWarnings("unchecked")
	// public void testGetIOFactoryIllegalAccessException() throws InstantiationException, IllegalAccessException {
	// final Class<IOFactory> classMock = createMock(Class.class);
	// expect(classMock.newInstance()).andThrow(new IllegalAccessException("test"));
	// m_map.put("", classMock);
	// replay(classMock);
	//
	// final IOFactory factory = IOMetaFactory.getInstance().getIOFactory("");
	//
	// assertNull(factory);
	// verify(classMock);
	// }
}
